package com.xh3140.xwidget.button;

import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.LinearLayoutCompat;


/**
 * 按钮组控件
 */
public class ButtonGroup extends LinearLayoutCompat {
  /**
   * 按钮位置
   */
  private static final int POSITION_NO = -1;
  private static final int POSITION_START = 0;
  private static final int POSITION_BETWEEN = 1;
  private static final int POSITION_END = 2;

  /**
   * 在按钮组中的位置枚举类
   */
  private enum GroupLocation {
    LEFT(new int[]{1, 0, 0, 1, 1, 1, 0, 1}),
    HORIZONTAL_BETWEEN(new int[]{0, 0, 0, 0, 0, 1, 0, 1}),
    RIGHT(new int[]{0, 1, 1, 0, 0, 1, 1, 1}),
    TOP(new int[]{1, 1, 0, 0, 1, 1, 1, 0}),
    VERTICAL_BETWEEN(new int[]{0, 0, 0, 0, 1, 0, 1, 0}),
    BOTTOM(new int[]{0, 0, 1, 1, 1, 0, 1, 1});

    /**
     * radius,inset调节因子,共8个值。
     * 前4个调节radius，后4个调节inset。
     */
    private final int[] factory;

    GroupLocation(final int[] factory) {
      this.factory = factory;
    }

    private int[] adjustRadius(final int[] radius) {
      radius[0] *= factory[0];
      radius[1] *= factory[1];
      radius[2] *= factory[2];
      radius[3] *= factory[3];
      return radius;
    }

    private int[] adjustInsets(final int[] insets) {
      insets[0] *= factory[4];
      insets[1] *= factory[5];
      insets[2] *= factory[6];
      insets[3] *= factory[7];
      return insets;
    }

    private void configButton(final Button button) {
      button.setRadius(adjustRadius(button.getRadius()));
      button.setInsets(adjustInsets(button.getInsets()));
    }
  }

  public ButtonGroup(@NonNull Context context) {
    super(context);
  }

  public ButtonGroup(@NonNull Context context, @Nullable AttributeSet attrs) {
    super(context, attrs);
  }

  public ButtonGroup(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
  }

  @Override
  public void addView(View child, int index, ViewGroup.LayoutParams params) {
    addViewCheckConfig(child, index, params);
    super.addView(child, index, params);
  }

  @Override
  protected boolean addViewInLayout(View child, int index, ViewGroup.LayoutParams params, boolean preventRequestLayout) {
    addViewCheckConfig(child, index, params);
    return super.addViewInLayout(child, index, params, preventRequestLayout);
  }

  /**
   * 添加子按钮之前配置按钮状态
   * 主要设置按钮的位置信息和宽度权重
   */
  private void addViewCheckConfig(View child, int index, ViewGroup.LayoutParams params) {
    if (!(child instanceof Button)) {
      throw new IllegalStateException("Cannot add a not Button view to a ButtonGroup.");
    }
    final int childCount = getChildCount();
    final Button button = (Button) child;
    if (childCount == 0) {
      setChildPosition(button, (index == 0) ? POSITION_NO : POSITION_START);
    } else if (childCount == 1) {
      final Button first = (Button) getChildAt(0);
      if (index == 0) {
        setChildPosition(button, POSITION_START);
        setChildPosition(first, POSITION_END);
      } else {
        setChildPosition(first, POSITION_START);
        setChildPosition(button, POSITION_END);
      }
    } else {
      if (index == 0) {
        final Button first = (Button) getChildAt(0);
        setChildPosition(button, POSITION_START);
        setChildPosition(first, POSITION_BETWEEN);
      } else if (index == -1 || index == childCount) {
        final Button last = (Button) getChildAt(childCount - 1);
        setChildPosition(last, POSITION_BETWEEN);
        setChildPosition(button, POSITION_END);
      } else {
        setChildPosition(button, POSITION_BETWEEN);
      }
    }
    if (params instanceof LayoutParams && ((LayoutParams) params).weight == 0f) {
      ((LayoutParams) params).weight = 1f;
    }
  }

  private void setChildPosition(Button button, int position) {
    final boolean isHorizontal = getOrientation() == HORIZONTAL;
    if (position == POSITION_START) {
      setGroupLocation(button, isHorizontal ? GroupLocation.LEFT : GroupLocation.TOP);
    } else if (position == POSITION_BETWEEN) {
      setGroupLocation(button, isHorizontal ? GroupLocation.HORIZONTAL_BETWEEN : GroupLocation.VERTICAL_BETWEEN);
    } else if (position == POSITION_END) {
      setGroupLocation(button, isHorizontal ? GroupLocation.RIGHT : GroupLocation.BOTTOM);
    }
  }

  private void setGroupLocation(Button button, GroupLocation location) {
    location.configButton(button);
  }
}
